﻿using HCMS.CommonDtos;
using HCMS.Entities.Manage;
using HCMS.Extensions;
using HCMS.IServices.Manage;
using HCMS.Utils;
using HCMS.Web.Manage.ServicesExtensions.SignalExt;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;

namespace HCMS.Web.Manage.Controllers.Module.Manage
{
    /// <summary>
    /// 管理员
    /// </summary>
    public class AdminController : ModuleController
    {
        private readonly IAdminAppService adminAppService;
        private readonly IAdminRoleAppService adminRoleAppService;
        private readonly IRoleAppService roleAppService;

        private readonly IHubContext<SystemMsgHub> hubContext;

        public AdminController(
            IAdminAppService adminAppService,
            IAdminRoleAppService adminRoleAppService,
            IRoleAppService roleAppService,
            IHubContext<SystemMsgHub> hubContext
        )
        {
            this.adminAppService = adminAppService;
            this.adminRoleAppService = adminRoleAppService;
            this.roleAppService = roleAppService;
            this.hubContext = hubContext;
        }

        #region 列表
        /// <summary>
        /// 列表
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult List()
        {
            return View($"{BasePath}/Manage/Admin/List.cshtml");
        }

        /// <summary>
        /// 列表 Ajax
        /// </summary>
        /// <returns></returns>
        [ActionName("List")]
        [HttpPost]
        public async Task<IActionResult> PostList()
        {
            var searchArgs = new SearchArgsDto()
            {
                Status = Request.Form["status"].ToInt(9999),

                SearchName = Request.Form["searchName"].ToString(""),
                SearchKey = Request.Form["searchKey"].ToString("")
            };

            var pager = new PagerArgsDto()
            {
                CurrentPageIndex = Request.Form["page"].ToInt(1),
                PageSize = Request.Form["limit"].ToInt(10)
            };

            var result = await adminAppService.ManageList(searchArgs, pager);

            return Json(new { code = 0, data = result.Data, count = result.PagerInfo.RowCount, msg = "ok" });
        }
        #endregion

        #region 新增、编辑、保存
        /// <summary>
        /// 新增
        /// </summary>
        /// <returns></returns>
        public IActionResult Add()
        {
            var model = new Admin();
            ViewData["roleId"] = 0;
            return View($"{BasePath}/Manage/Admin/Edit.cshtml", model);
        }

        /// <summary>
        /// 编辑
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> Edit(int id)
        {
            if (id <= 0)
            {
                return Content("参数无效");
            }

            var model = await adminAppService.BaseFirstOrDefaultAsync(t => t.Id == id);
            if (model == null)
            {
                return Content($"没有找到【id：{id}】管理员信息");
            }

            var roleId = 0;
            var adminRole = await adminRoleAppService.BaseFirstOrDefaultAsync(t => t.AdminId == model.Id && t.Status == 0);
            if (adminRole != null)
            {
                roleId = adminRole.RoleId;
            }
            ViewData["roleId"] = roleId;

            // 测试代码，主动刷新客户端消息
            // 根据实际业务调用。例如新增资讯后，服务器主动刷新编辑人员后台的【消息中心】，将最新的待审核消息告知
            //await hubContext.Clients.User(model.Id.ToString()).SendAsync("MessageCenterRefresh", "收到新消息");

            return View($"{BasePath}/Manage/Admin/Edit.cshtml", model);
        }

        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="admin"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> Save(Admin admin)
        {
            Admin? result = null;

            if (admin == null)
            {
                return Json(new AjaxResultDto() { Code = 500, Message = "参数错误" });
            }
            if (string.IsNullOrWhiteSpace(admin.AdminName))
            {
                return Json(new AjaxResultDto() { Code = 500, Message = "请填写姓名" });
            }
            if (string.IsNullOrWhiteSpace(admin.PassWord))
            {
                return Json(new AjaxResultDto() { Code = 500, Message = "请填写密码" });
            }

            var roleId = Request.Form["roleId"].ToInt(0);

            var entity = await adminAppService.BaseFirstOrDefaultAsync(t => t.Id == admin.Id);
            if (entity != null)
            {
                // 是否需要重置登录状态
                bool isResetLogined = false;

                bool isChangePassword = Request.Form["IsChangePassword"].ToBool(false);
                if (isChangePassword)
                {
                    isResetLogined = true;
                    entity.PassWord = MD5EncryptUtil.MD5Encrypt(admin.PassWord + entity.Salt);
                }
                if (entity.AdminName != admin.AdminName)
                {
                    isResetLogined = true;
                }
                if (entity.Status != admin.Status)
                {
                    isResetLogined = true;
                }

                // 角色发生变更，需要重新登录
                int originalRoleId = Request.Form["OriginalRoleId"].ToInt(0);
                if (roleId != originalRoleId)
                {
                    isResetLogined = true;
                }

                entity.AdminName = admin.AdminName;
                entity.Logo = admin.Logo;
                entity.Status = admin.Status;
                entity.UseApiDoc = admin.UseApiDoc;
                entity.UpdateTime = DateTime.Now;
                entity.UpdateUser = CurrentAdmin.AdminName;

                // 重置管理员登录状态
                if (isResetLogined)
                {
                    // 重置 redis 登录状态
                    long timestamp = DateTimeUtil.GetTimestamp();
                    var expiredTime = DateTimeOffset.Parse($"{DateTimeOffset.Now:yyyy-MM-dd 23:59:59}");
                    await adminAppService.SetLoginedInfo(entity.Id, timestamp, DateTimeUtil.DifferenTimespan(DateTime.Now, expiredTime));

                    // 推送【下线消息】给目前在线的管理员
                    await hubContext.Clients.User(entity.Id.ToString()).SendAsync("LogoutMsg", "您已下线，请重新登录");
                }
                entity = EntityConvertUtil.FieldsNullConvertDefault(entity);
                result = await adminAppService.BaseUpdateAsync(entity);
            }
            else
            {
                string salt = RandomUtil.GetRandomString("", 11);

                entity = new Admin()
                {
                    CreateTime = DateTime.Now,
                    CreateUser = CurrentAdmin.AdminName,
                    UpdateTime = DateTime.Now,
                    UpdateUser = CurrentAdmin.AdminName,
                    Logo = admin.Logo,
                    AdminName = admin.AdminName,
                    Salt = salt,
                    PassWord = MD5EncryptUtil.MD5Encrypt(admin.PassWord + salt),
                    Status = admin.Status,
                    UseApiDoc = admin.UseApiDoc
                };
                entity = EntityConvertUtil.FieldsNullConvertDefault(entity);
                result = await adminAppService.BaseInsertAsync(entity);
            }

            if (result != null)
            {
                if (result.Id > 0)
                {
                    if (roleId == 0)
                    {
                        return Json(new AjaxResultDto() { Code = 500, Message = "请选择角色" });
                    }
                    var role = await roleAppService.BaseFirstOrDefaultAsync(t => t.Id == roleId && t.Status == 0);
                    if (role == null)
                    {
                        return Json(new AjaxResultDto() { Code = 500, Message = "角色不存在，请重新选择" });
                    }

                    await adminRoleAppService.SetAdminRole(result.Id, roleId, "系统");
                }

                return Json(new AjaxResultDto() { Message = "处理成功" });
            }
            else
            {
                return Json(new AjaxResultDto() { Code = 500, Message = "处理失败" });
            }
        }
        #endregion
    }
}
